import javax.media.opengl.*;
import jocode.*;
import processing.opengl.*;

JOApp joApp;
// handle for texture
int sphereTextureHandle = 0;
// lighting colors
float faWhite[]      = { 1.0f, 1.0f, 1.0f, 1.0f };
float faLightBlue[]  = { 0.8f, 0.8f, .9f, 1f };
// light position: 
//  if last value is 0, then this describes light direction.  
//  if 1, then light position.
float lightPosition[]= { -4f, 3f, 3f, 1.0f };
// world coordinates of sphere
float[] spherePos = { 0f, 0f, 0f};
// rotation of sphere
float rotation = 0;
// image to draw as 2D overlay over 3D scene, and texture handle for it
JOImage overlayImage;
int overlayTextureHandle = 0;
// cursor is a texture drawn onto a quad
int cursorTextureHandle = 0;

PFont font;

void setup() {
  size(800, 600, OPENGL);
  noCursor();
  font = loadFont("Tahoma.vlw");
  textFont(font);
  
  joApp = JOBridgeP5.init(this);
  
  // load the textures
  sphereTextureHandle = JOApp.makeTexture("eye.jpg");
  cursorTextureHandle = JOApp.makeTexture("cursorCrosshair32.gif");

  // load the image for 2D overlay and make it a texture
  overlayImage = JOApp.loadImage("frame_ornate3.gif");
  overlayTextureHandle = JOApp.makeTexture(overlayImage);
}

void setPerspective() {
  // select projection matrix (controls perspective)
  JOApp.gl.glMatrixMode(GL.GL_PROJECTION);
  JOApp.gl.glLoadIdentity();
  // fovy, aspect ratio, zNear, zFar
  JOApp.glu.gluPerspective(30f, JOApp.aspectRatio, 1f, 100f);
  // return to modelview matrix
  JOApp.gl.glMatrixMode(GL.GL_MODELVIEW);
}

void draw() {
  rotation += .5f;

  JOApp.begin();
  {
    setPerspective();

    // create a light (diffuse light, ambient light, position)
    JOApp.setLight(GL.GL_LIGHT1, faWhite, faWhite, faLightBlue, lightPosition);

    // enable lighting and texture rendering
    JOApp.gl.glEnable(GL.GL_LIGHTING);
    JOApp.gl.glEnable(GL.GL_TEXTURE_2D);

    // enable alpha transparency (for overlay image)
    JOApp.gl.glEnable(GL.GL_BLEND);
    JOApp.gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

    // clear depth buffer and color
    JOApp.gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

    // select model view for subsequent transforms
    JOApp.gl.glMatrixMode(GL.GL_MODELVIEW);
    JOApp.gl.glLoadIdentity();

    // set the viewpoint
    JOApp.glu.gluLookAt(0f, 0f, 15f,  // where is the eye
                        0f, 0f, 0f,   // what point are we looking at
                        0f, 1f, 0f);  // which way is up

    // draw sphere at center, in perspective
    JOApp.gl.glPushMatrix();
    {
      JOApp.gl.glTranslatef(spherePos[0], spherePos[1], spherePos[2]);
      JOApp.gl.glRotatef(-90, 1, 0, 0);                               // rotate around X axis
      JOApp.gl.glRotatef(rotation, 0, 0, 1);                          // rotate around Y axis
      JOApp.gl.glBindTexture(GL.GL_TEXTURE_2D, sphereTextureHandle);  // activate texture
      JOApp.renderSphere();                                           // draw the sphere
    }
    JOApp.gl.glPopMatrix();

    // turn off lighting so image will draw as-is, not lit
    JOApp.gl.glDisable(GL.GL_LIGHTING);

    // drawQuad() and drawCursor call setOrthoOn() to render in 2D mode
    // then call setOrthoOff() to return to previous state (perspective).

    // overlay Image: draw image in 2D (ortho mode) as a texture on a quad.
    float zoom = mouseX / (float)width * 2f;   // mouse motion scales the image
    JOApp.drawQuad(overlayTextureHandle,                             // image will be texture on a square
                   int((width  / 2) - (overlayImage.w * zoom / 2)),  // center image
                   int((height / 2) - (overlayImage.h * zoom / 2)),
                   overlayImage.w * zoom,                            // scale width and height
                   overlayImage.h * zoom);

    // draw the cursor as a 2D quad on top of scene
    JOApp.drawCursor(cursorTextureHandle);
    
    // rectangle
    JOApp.setColor(.7f, .6f, .5f, 1f);
    JOApp.setLineWidth(2);
    JOApp.drawRect(10,10,505,40);
  }
  JOApp.end();
  
  fill(179, 153, 128);
  text("Use Ortho mode to render in 2D over the scene.", 15, height-22);
}

void mouseMoved() {
  joApp.mouseMoved(mouseEvent);
}

void mouseDragged() {
  joApp.mouseDragged(mouseEvent); 
}
